﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Security.Principal;
using System.Runtime.Remoting.Messaging;
using System.Diagnostics;
using BusinessLogic.Entities;

namespace BusinessLogic.Security
{
    /// <summary>
    /// Информация о пользователе
    /// </summary>
    public class UserPrincipal : IPrincipal
    {
        public UserPrincipal()
        {

        }

        public const string CALL_CONTEXT_KEY = "SecurityContext";


        #region Свойства пользователя


        public int UserId { get; set; }
        public string UserFullName { get; set; }
        public string LoginName { get; set; }
        public string UserPhone { get; set; }
        public string UserEmail { get; set; }

        #endregion Свойства пользователя

        public bool OnliIts { get; set; }
        public List<MenuEntity> MenuItems { get; set; }
        public List<StateEntity> StateItems { get; set; }
        public List<MVCActionEntity> MVCActionItems { get; set; }
        public List<RoleGroupEntity> RoleGroups { get; set; }


        public static UserPrincipal Current
        {
            get
            {
                UserPrincipal result;
                if (null != HttpContext.Current.User as UserPrincipal)
                {
                    result = (UserPrincipal)HttpContext.Current.User;
                }
                else
                {
                    result = CallContext.GetData(CALL_CONTEXT_KEY) as UserPrincipal;
                }
                return result;
            }
        }


        #region IPrincipal Members

        class SimpleIdentity : IIdentity
        {
            public string Name { get; set; }

            public string AuthenticationType { get; set; }

            public bool IsAuthenticated { get; set; }
        }

        public IIdentity Identity
        {
            get
            {
                return new SimpleIdentity
                {
                    Name = UserFullName,
                    AuthenticationType = null,
                    IsAuthenticated = UserId != -1
                };
            }
        }

        public virtual bool IsInRole(string role)
        {
            return IsActivityAllowed(role);
        }

        #endregion


        public static UserPrincipal LoginToApplication(string DomainLoginName)
        {
            UserPrincipal result = new UserPrincipal();
            result.LoginName = DomainLoginName;
            try
            {
                ServiceClients.AuthClient client = new ServiceClients.AuthClient();
                var user = client.GetUserSecurityDetails(DomainLoginName);

                if (user == null)
                    throw new Exception(string.Format("Пользователь с учетной записью: {0}, не зарегистрирован в системе.", DomainLoginName));

                //// Getting user details
                result.UserId = user.Id;
                result.UserFullName = user.FIO;
                result.LoginName = user.Login;
                result.UserPhone = user.Phone;
                result.UserEmail = user.Email;
                bool isEnabled = user.Enabled;
                if (!isEnabled)
                    throw new Exception(string.Format("Пользователь с учетной записью: {0}, заблокирован в системе.", DomainLoginName));

                //// Getting permission items
                //if (ds.Tables.Count > 1 && ds.Tables[1] != null && ds.Tables[1].Rows != null && ds.Tables[1].Rows.Count > 0)
                //{
                //    result.AvailableActivities = ds.Tables[1].Copy();
                //}


                if (user.Groups != null && user.Groups.Count > 0)
                {
                    result.RoleGroups = user.Groups;

                    var menus = new List<MenuEntity>();
                    var mvcActions = new List<MVCActionEntity>();
                    var states = new List<StateEntity>();
                    foreach (var group in user.Groups)
                    {
                        foreach (var role in group.Roles)
                            menus.AddRange(role.PermissionMenus.Select(p => p.Menu));

                        foreach (var role in group.Roles)
                            mvcActions.AddRange(role.PermissionMVCActions.Select(p => p.MVCAction));

                        foreach (var role in group.Roles)
                            states.AddRange(role.PermissionStates.Select(p => p.State));   
                    }
                    result.MenuItems = menus.Distinct().ToList();
                    result.MVCActionItems = mvcActions.Distinct().ToList();
                    result.StateItems = states.Distinct().ToList();
                }
            }
            catch (Exception ex)
            {
                return null;
            }

            return result;
        }


        /// <summary>
        /// Аутентификация пользователя в БД
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="password"></param>
        /// <returns>1-OK, 2-пользователь заблокирован, 0-неправильный логин/пароль</returns>
        public static int AuthenticateUser(string userName, string password)
        {
            string hashPassword = String.IsNullOrEmpty(password) ? "" : PasswordMD5Helper.GetMd5Hash(password);

            ServiceClients.AuthClient client = new ServiceClients.AuthClient();
            int result = client.AuthenticateUser(userName, hashPassword);

            return result;
        }


        /// <summary>
        /// Есть ли право переводить в указанный статус у текущего пользователя
        /// </summary>
        /// <param name="stateId"></param>
        /// <returns></returns>
        public bool ExistStatePermission(int stateId)
        {
            if (Current == null || Current.StateItems == null)
                return false;

            var statePermission = Current.StateItems.Where(s => s.Id == stateId).FirstOrDefault();
            return (statePermission != null) ? true : false;
        }


        public bool IsActivityAllowed(string roleName)
        {
            if (RoleGroups == null || RoleGroups.Count == 0)
                return false;

            return RoleGroups.Exists(g => g.Roles.Exists(r => r.Name.ToLower() == roleName.ToLower()));
        }



    }
}
